package com.coder.rental.utils;

import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateTime;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;

import java.util.Map;

/**
 * @author: zhanglin
 * @description:  jwt工具类
 * @date 2025/3/20
 */
public class JwtUtils {
    //jwt密钥
    public static final String SECRET_KEY= "car_zhanglin";
    //过期时间：L是毫秒，1000毫秒-1秒，乘60是1分钟，乘于30是30分钟。
    public static  final long EXPIRE_TIME = 1000L*60*30;
    /*
    * 生成token
    * map是键值对的数据结构，键值String类型，值是Object类型，载荷可能有种的数据类型，将JWTPayload载荷封装为字符串。
    * */
    public static String createToken(Map<String,Object> payload){
        DateTime now = DateTime.now();
        DateTime newTime = new DateTime(now.getTime()+EXPIRE_TIME);
        //设置签发时间
        payload.put(JWTPayload.ISSUED_AT, now);
        //设置过期时间
        payload.put(JWTPayload.EXPIRES_AT, newTime);
        //设置生效时间，确保token在签发后立即生效
        payload.put(JWTPayload.NOT_BEFORE, now);
        //返回token ，SECRET_KEY.getBytes()是设置字符编码，将字符串转换为字节码数组
        return JWTUtil.createToken(payload, SECRET_KEY.getBytes());
    }
    /*
    * 解析token
    * */
    public static JWTPayload parseToken(String token){
        JWT jwt = JWTUtil.parseToken(token);
        /*
        * verify()是jwt的验证库中的方法，验证jwt是否有效（签名验证、过期时间验证、发行时间验证）
        * */
        if(!jwt.setKey(SECRET_KEY.getBytes()).verify()){
            throw new RuntimeException("token异常");
        }
        /*
        *  validate()解析token中的过期时间，判断token是否已经过期
        * */
        if(!jwt.validate(0)){
            throw new RuntimeException("token已过期");
        }
        return jwt.getPayload();
    }

    /*
    * 测试
    * */
    public static void main(String[] args) {
        // // 生成token测试
        // // 用户的基本信息在载荷payload里
        // Map<String, Object> payload = new HashMap<>();
        // payload.put("username", "zhanglin");
        // payload.put("id", "777777");
        // String token = createToken(payload);
        // System.out.println(token);

        // 解析token测试
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE3NDI0NjM4NTQsImlkIjoiNzc3Nzc3IiwiZXhwIjoxNzQyNDY1NjU0LCJpYXQiOjE3NDI0NjM4NTQsInVzZXJuYW1lIjoiemhhbmdsaW4ifQ.vZQW2K3bftULlafU4ilM568YU6TFlZZ27Dsn85DqOLE";
        JWTPayload payload = parseToken(token);
        System.out.println(payload.getClaim("username"));
        System.out.println(payload.getClaim("id"));
        //获取过期时间，得到的是一个对象，需要进行转换
        // Object claim = payload.getClaim(JWTPayload.EXPIRES_AT);
        NumberWithFormat claim = (NumberWithFormat) payload.getClaim(JWTPayload.EXPIRES_AT);
        DateTime convert = (DateTime) claim.convert(DateTime.class, claim);
        long expireTime = convert.getTime();
        long nowTime = DateTime.now().getTime();//当前时间
        System.out.println("有效时间还剩："+(expireTime-nowTime)/1000+"秒");

    }
}
